# -*- coding: utf8 -*-

import traceback
from time import sleep
from worker import Worker
from time import time

class FileHashCalcWorker( Worker ):

    my_query_name = "hashes"

    read_chunk = 64 * 1024

    def run ( self ):

        print("FileHashCalcWorker: START: %s" % self.my_query_name)
        
        import hashlib
        
        p = self.app.get_project()
        sess = p.get_session()
        
        while not self.stop_event.isSet():
            
            try:
                data = self.app.get_queue(self.my_query_name).get_nowait()
            except:
                data = None
            
            if data is None:
                sleep(0.01)
                continue

            file_id, device, file_size, full_path = data

            f = None
            shash = None
            try:
                self.app.get_stats().set_hashing( device, full_path, file_size, 0, time() )
                
                alg = hashlib.new(self.app.get_option("hash_function"))
                f = open( full_path, "rb" )

                rs = 0
                rds = 0
                t_last = time()
                while 1:
                    if self.stop_event.isSet():
                        break
                    rd = f.read( self.read_chunk )
                    rds = len(rd)
                    if rds > 0:
                        alg.update(rd)
                        rs += rds
                        if time() - t_last >= 0.1:
                            t_last = time()
                            self.app.get_stats().inc("real_readed_size", rs )
                            self.app.get_stats().inc("readed_size", rs )
                            self.app.get_stats().inc_hashing(device, rs )
                            rs = 0
                    else:
                        break
                f.close()
                f = None
                self.app.get_stats().inc("real_readed_size", int(rs) )
                self.app.get_stats().inc("readed_size", int(rs) )
                self.app.get_stats().inc_hashing(device, int(rs) )
                shash = alg.hexdigest()
            except:
                print("FileHashCalcWorker: ERROR!\n File: '%s'\n%s" % (
                    full_path, traceback.format_exc()))
                if f:
                    f.close()
            
            if shash:
                hitem = p.find_hash( shash )
                if hitem:
                    self.app.get_stats().inc("nonunique_count", 1)
                    self.app.get_stats().inc("nonunique_size", file_size)
                    self.app.get_stats().inc("nonunique_count_now", 1)
                    self.app.get_stats().inc("nonunique_size_now", file_size)

                    p.update_hash( hitem, file_id )
                else:
                    self.app.get_stats().inc("unique_count", 1)
                    hitem = p.insert_hash( file_id, shash )

                sess.expunge(hitem)

                self.app.get_stats().inc("hashed_count", 1)
            else:
                self.app.get_stats().inc("errors_count", 1)
                
            self.app.get_stats().inc("files_processed", 1)

            self.app.get_queue(self.my_query_name).task_done()
        
        print("FileHashCalcWorker: STOP: %s" % self.my_query_name)

        p.close_session()

        self.stop_event.clear()
        return
